#ifndef _TYPEC_PD_CONFIG_H_
#define _TYPEC_PD_CONFIG_H_

#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define CONFIG_USBPD_SUPPORT

#ifndef MIN
#define MIN(a, b)           (((a) < (b)) ? (a) : (b))
#endif

struct pd_message {
    uint8_t frame_type;
    uint16_t msg_hdr;
    uint32_t payload[7];
    uint8_t msg_type;
};

struct pd_protocol_layer {
    uint8_t prl_tx_state;

    /* Table 6.70 counters */
    uint8_t ncapscount;
    uint8_t nmessageidcount; // shall be 0 after soft_reset or hard_reset
    uint8_t nhardresetcount;

    /* collision */
    uint8_t traffic_control;
};

struct pd_policy_engine {
    uint8_t pe_state_old;
    uint8_t pe_state;
    bool explicit_contract;
    bool in_pr_swap;
    bool prs_to_src;
    bool in_hard_reset;
};

struct pd_port_power_capabilities {
    uint8_t number;
    uint32_t pdos[7];
};

struct pd_port_info {
    uint8_t power_role;
    uint8_t data_role;
    uint8_t vconn_role;
    bool need_vconn;
    uint8_t pd_revision[2]; // 0-SOP, 1-SOPP
    uint8_t pd_vdm_revision[2];
    uint16_t vdm_svid;
    uint8_t vdm_mode_idx;
    bool pd_connected;
    bool pd_rev_synced;
    uint16_t request_mv;
    uint16_t request_ma;
    struct pd_port_power_capabilities local_src_cap;
    struct pd_port_power_capabilities local_snk_cap;
    struct pd_port_power_capabilities remote_src_cap;
    struct pd_port_power_capabilities remote_snk_cap;
    uint32_t vdos[7]; // Discover ID VDO
    uint32_t rdo;
    bool pps_rdo;
};

#define PD_MSG_RX_FIFO_SIZE     4
struct pd_msg_rx_fifo {
    struct pd_message buf[PD_MSG_RX_FIFO_SIZE];
    uint8_t r_idx;
    uint8_t w_idx;
    uint8_t cnt;
};

struct typec_port_info {
    uint16_t vid;
    uint16_t pid;
    uint16_t did;

    /* configuration */
    uint8_t local_rplvl;
    uint8_t rp_level;  // real-time rp level
    bool hw_auto_toggle;

    /* typec state */
    uint8_t vbus_sts;
    uint8_t cc1_sts;
    uint8_t cc2_sts;
    uint8_t cc_orient;
    uint8_t typec_state_old;
    uint8_t typec_state;

    /* typec event */
    bool cc_changed;
    bool vbus_changed;
    uint8_t typec_expired_timer;

    /* pd event */
    uint8_t pd_expired_timer;
    uint8_t pd_event;
    bool pd_msg_received;
    struct pd_message pd_msg;
    struct pd_msg_rx_fifo pd_msg_rxf;
    struct pd_protocol_layer pd_protocol;
    struct pd_policy_engine pd_pe;
    struct pd_port_info pd_port;

    /* power supply */
    bool vbus_on;
    uint16_t out_mv;
    uint16_t out_ma;
    uint16_t in_ma;

    /* dpm policy */
    bool dpm_ongoing;
    bool dpm_tx_ready;
    uint32_t dpm_policy;
    uint32_t dpm_reactions;
};

extern volatile uint32_t g_sys_ticks;
extern struct typec_port_info tpc_port;

void delay_1ms(uint32_t n);

#endif
